import 'reflect-metadata'

const METHOD_METADATA = 'method'
const PATH_METADATA = 'path'

const Controller = (path: string): ClassDecorator => {
	return target => {
		Reflect.defineMetadata(PATH_METADATA, path, target)
	}
}

const createMappingDecorator = (method: string) => (path: string): MethodDecorator => {
	return (target, key, descriptor) => {
		Reflect.defineMetadata(PATH_METADATA, path, descriptor.value as any)
		Reflect.defineMetadata(METHOD_METADATA, method, descriptor.value as any)
	}
}

const Get = createMappingDecorator('GET')
const Post = createMappingDecorator('POST')

function mapRoute(instance: Object) {
	const prototype = Object.getPrototypeOf(instance)
	const names = Object.getOwnPropertyNames(prototype)
	const methodsNames = names.filter(item => item !== 'constructor')
	return methodsNames.map(methodsName => {
		const fn = prototype[methodsName]
		const route = Reflect.getMetadata(PATH_METADATA, fn)
		const method = Reflect.getMetadata(METHOD_METADATA, fn)
		return {
			route,
			method,
			fn,
			methodsName,
		}
	})
}

@Controller('/test')
class MyController {
	@Get('/a')
	findAll() {}

	@Post('/b')
	newPost() {}
}

console.log(Reflect.getMetadata(PATH_METADATA, MyController))
const myController = new MyController()
const d = mapRoute(myController)
console.log(JSON.stringify(d))
console.log('here')
